#pragma once

#include <QObject>
#include <QColor>
#include <QSizeF>
#include <QPointF>
#include <QRectF>
#include <QImage>


class GraphicsBaseItem;

class GraphicsBaseItemData : public QObject
{
	Q_OBJECT
public:
	// 图元类型
	enum BaseItemType {
		Box_Enum,
		Image_Enum,
		Drawing_Enum,
		Origin_Enum
	};
	Q_ENUM(BaseItemType);

	// 图元模式
	enum BaseItemMode
	{
		Free_Enum,// 自由模式
		Fix_Enum// 固定模式
	};

	// 图元的信息
	struct BaseItemInfo
	{
		QPointF pos;// 坐标点
		qreal scale;// 缩放系数
		QRectF rect;// 形状信息
		qreal angle;// 旋转角度
	};

	GraphicsBaseItemData(BaseItemType type, GraphicsBaseItem* parent);

	BaseItemType getBaseItemType()const { return m_baseItemType; }

	int getPenWidth()const { return m_penWidth; }

	bool isHover()const { return m_isHover; }

	void setHover(bool isHover) { m_isHover = isHover; }

	QColor getBorderColor()const { return m_borderColor; }

	void setBorderColor(const QColor& color) { m_borderColor = color; }

	void setRealMinSize(const QSizeF& minSize) { m_minSize = minSize; }

	QSizeF getRealMinSize()const { return m_minSize; }

	QSizeF getScaleMinSize()const { return m_minSize * getItemScale(); }

	QSizeF getScaleMaxSize()const { return m_maxSize * getItemScale(); }

	void setRealMaxSize(const QSizeF& maxSize) { m_maxSize = maxSize; }

	QSizeF getRealMaxSize()const { return m_maxSize; }

	// 保存上下文信息(带缩放系数)
	void saveContext();

	BaseItemInfo getContext()const { return m_context; }

	void setIsOriginOnCenter(bool originIsOnCenter) { m_originIsOnCenter = originIsOnCenter; }

	bool IsOriginOnCenter()const { return m_originIsOnCenter; }

	BaseItemInfo getPressItemInfo()const { return m_pressItemInfo; }

	BaseItemInfo getItemInfo()const;

	QMap<GraphicsBaseItem*, BaseItemInfo> getChildsInfoMap()const;

	// 保存点击时候的图元信息(带缩放系数)
	void savePressContext();

	void setPressItemInfo(const BaseItemInfo& info) { m_pressItemInfo = info; }

	void setOperationStartMousePoint(const QPointF& point) { m_operationStartMousePoint = point; }

	QPointF getOperationStartMousePoint()const { return m_operationStartMousePoint; }

	void setOperationDoingMousePoint(const QPointF& point) { m_operationDoingMousePoint = point; }

	QPointF getOperationDoingMousePoint()const { return m_operationDoingMousePoint; }

	void setExpandMode(BaseItemMode mode) { m_itemMode = mode; }

	BaseItemMode getExpandMode()const { return m_itemMode; }

	void setBoundingRect(const QRectF& boundingRect) { m_boundingRect = boundingRect; }

	QRectF getBoundingRect()const { return m_boundingRect; }

	void setRealSize(const QSizeF& size);

	QSizeF getRealSize()const { return m_boundingRect.size(); }

	void setScaleSize(const QSizeF& scaleSize);

	QSizeF getScaleSize()const;

	// 设置缩放比例
	void setItemScale(qreal scale);

	// 获取缩放比例
	qreal getItemScale()const { return m_scale; }

	void setParentItem(GraphicsBaseItem* parent) { m_parentItem = parent; }

	GraphicsBaseItem* getParentItem()const { return m_parentItem; }

	// 添加图元
	void addChild(GraphicsBaseItem* child);

	QVector<GraphicsBaseItem*> getChilds()const { return m_childs; }

	void setRotateAngle(qreal angle, bool sendSignal = true);

	qreal getRotateAngle()const { return m_rotateAngle; }

	void setCurPos(const QPointF& pos, bool isSendChanged = true);

	QPointF getCurPos()const { return m_curPos; }

	// 获取在场景中图元的缩放尺寸
	QRectF getScaleRect()const;

	// 获取实际尺寸
	QRectF getRealRect()const;

	// 设置图片的宽高比
	void setBaseItemAspectRatio(qreal aspectRatio) { m_aspectRatio = aspectRatio; }

	// 获取图片的宽高比
	qreal getBaseItemAspectRatio()const { return m_aspectRatio; }

	// 固定模式下，设置边角点拉伸需要保存的宽高比
	void setFixRatio(qreal fixRatio) { m_fixRatio = fixRatio; }

	// 固定模式下，获取边角点拉伸需要保存的宽高比
	qreal getFixRatio()const { return m_fixRatio; }

	// 设置是否可以移动
	void setMovable(bool isMovable) { m_isCanMoveable = isMovable; };

	// 获取当前图元是否可以移动
	bool isMovable()const { return m_isCanMoveable; }

	// 设置是否正在移动中
	void setIsMoving(bool isMoving) {
		m_isMoving = isMoving;
		emit sigMoving();
	};

	// 获取是否正在移动
	bool isMoving()const { return m_isMoving; }

	// 显示模式
	void setItemMode(GraphicsBaseItemData::BaseItemMode mode, qreal fixRatio);

	// 设置遮罩
	void setMaskImage(const QImage& mask);

	// 获取遮罩
	QImage getMaskImage()const { return m_maskImage; }

	void setDefaultSize(const QSize& size) { m_defaultSize = size; }

	QSize getDefaultSize()const { return m_defaultSize; }

	void setOriginImage(const QImage& image) { m_originImage = image; }

	QImage getOriginImage()const { return m_originImage; }
signals:
	// 缩放比例变化
	void sigItemScaleChanged(qreal newScale);

	// 位置变化
	void sigPositionChanged(const QPointF& pos);

	// 尺寸变化
	void sigSizeChanged();

	// 旋转角度变化
	void sigRotateAngleChanged(qreal angle);

	// 遮罩变化
	void sigMaskChanged();

	// 正在拖动
	void sigMoving();
private:
	// 获取在场景中图元的尺寸,isScale是否加上缩放
	QRectF getRect(bool isScale = true)const;
private:
	// 图元类型
	const BaseItemType m_baseItemType;
	// 图元尺寸(没加缩放系数)
	QRectF m_boundingRect;
	// 边框色
	QColor m_borderColor;
	// box为场景中尺寸，image和draw为图片原尺寸
	QSize m_defaultSize = QSize(0, 0);
	// 是否在hover状态
	bool m_isHover = false;
	// 画笔宽度
	const int m_penWidth = 2;
	// 最小尺寸
	QSizeF m_minSize;
	// 最大尺寸
	QSizeF m_maxSize;
	// 记录图元位置信息的上下文(带缩放系数)
	BaseItemInfo m_context;
	// 是否以图元中心为原点
	bool m_originIsOnCenter = false;
	// *************用于撤销和重做***************
	// 控制点或者自己的鼠标按下时候，图元的信息
	BaseItemInfo m_pressItemInfo;
	// 控制点按下时候，鼠标所在位置
	QPointF m_operationStartMousePoint;
	// 控制点正在操作时候，鼠标所在位置
	QPointF m_operationDoingMousePoint;
	// *********************************
	// 图元模式
	BaseItemMode m_itemMode = BaseItemMode::Free_Enum;
	// 缩放系数
	qreal m_scale = 1.0;
	// 父图元
	GraphicsBaseItem* m_parentItem = nullptr;
	// 子图元
	QVector<GraphicsBaseItem*> m_childs;
	// 旋转角度
	qreal m_rotateAngle = 0;
	// 当前坐标
	QPointF m_curPos;
	// 图片的宽高比
	qreal m_aspectRatio = 1.0;
	// 固定尺寸的比例
	qreal m_fixRatio = 1.0;
	// 是否可以移动
	bool m_isCanMoveable = false;
	// 是否在移动
	bool m_isMoving = false;
	// 遮罩
	QImage m_maskImage;
	// 原图
	QImage m_originImage;
};

using GraphicsItemInfo = GraphicsBaseItemData::BaseItemInfo;
using GraphicsItemMode = GraphicsBaseItemData::BaseItemMode;
using GraphicsItemType = GraphicsBaseItemData::BaseItemType;